
/**
* 上海中赢金融信息服务有限公司
* Copyright (c) 2017-2027 Chinazyjr,Inc.All Rights Reserved.
*/
package com.sys.midware.redis.core.operation;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.sys.midware.assist.serialize.SerializeUtil;
import com.sys.midware.assist.utils.Assert;
import com.sys.midware.redis.core.client.RedisClusterClient;
import com.sys.midware.redis.core.client.RedisJedisPoolClient;
import com.sys.midware.redis.core.operation.impl.ZSetTuple;
import com.sys.midware.redis.exceptions.BRedisException;
import com.sys.midware.redis.util.SerializationUtils;
import com.sys.midware.redis.util.StringRedisSerializer;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.Tuple;

/**
 * <b>Description：</b> 抽象操作类 <br/>
 * <b>ClassName：</b> AbstractOperations <br/>
 * <b>@author：</b> jackyshang <br/>
 * <b>@date：</b> 2016年8月22日 下午3:58:43 <br/>
 * <b>@version: </b> <br/>
 */
public abstract class AbstractOperations {

    public synchronized Jedis getClient() {
        Jedis client = RedisJedisPoolClient.getInstance().getClient();
        if (client == null) {
            throw new BRedisException("redis 连接获取异常!");
        }
        return client;
    }

    public synchronized JedisCluster getClient4Cluster() {
        JedisCluster client = RedisClusterClient.getInstance().getClient();
        if (client == null) {
            throw new BRedisException("redis-cluster 连接获取异常!");
        }

        return client;
    }

    protected byte[] rawKey(Object key) {
        Assert.notNull(key, "non null key required");
        if (key instanceof byte[]) {
            return (byte[]) key;
        }
        // return SerializeUtil.serialize(key);
        return StringRedisSerializer.serialize(key.toString());
    }

    // protected byte[] rawString(String key) {
    // return StringRedisSerializer.serialize(key);
    // }

    protected byte[] rawValue(Object value) {
        if (value instanceof byte[]) {
            return (byte[]) value;
        }
        return SerializeUtil.serialize(value);
    }

    @SuppressWarnings("unchecked")
    protected <K> K deserializeKey(byte[] value) {

        // return (K) SerializeUtil.unSerialize(value);

        return (K) StringRedisSerializer.deserialize(value);
    }

    @SuppressWarnings("unchecked")
    protected <V> V deserializeValue(byte[] value) {

        return (V) SerializeUtil.unSerialize(value);
    }

    protected <T> List<T> deserializeHashValues(List<byte[]> rawValues) {

        return SerializationUtils.deserialize(rawValues);
    }

    protected <V> List<V> deserializeValues(List<byte[]> rawValues) {

        return SerializationUtils.deserialize(rawValues);
    }

    protected <V> Set<V> deserializeValues(Set<byte[]> rawValues) {

        return SerializationUtils.deserialize(rawValues);
    }

    @SuppressWarnings("unchecked")
    protected <V> Set<ZSetTuple<V>> deserializeTupleValues(Set<Tuple> rawValues) {

        if (rawValues == null) {
            return null;
        }
        Set<ZSetTuple<V>> ztuple = new HashSet<>();

        for (Tuple tuple : rawValues) {
            ZSetTuple<V> zst = new ZSetTuple<V>((V) SerializeUtil.unSerialize(tuple.getBinaryElement()),
                    tuple.getScore());

            ztuple.add(zst);
        }
        return ztuple;
    }

    protected byte[][] rawKeys(Object... keys) {
        final byte[][] rawKeys = new byte[keys.length][];
        int i = 0;
        for (Object key : keys) {
            rawKeys[i++] = rawKey(key);
        }
        return rawKeys;
    }

    protected byte[][] rawValues(Object... values) {
        final byte[][] rawValues = new byte[values.length][];
        int i = 0;
        for (Object value : values) {
            rawValues[i++] = rawValue(value);
        }
        return rawValues;
    }

    protected <T> byte[][] rawValues(List<T> list) {
        final byte[][] rawValues = new byte[list.size()][];
        int i = 0;
        for (T value : list) {
            rawValues[i++] = rawValue(value);
        }
        return rawValues;
    }

    protected <V> Map<byte[], Double> rawTupleValues(Set<ZSetTuple<V>> values) {
        if (values == null) {
            return null;
        }
        Map<byte[], Double> map = new HashMap<byte[], Double>();
        for (ZSetTuple<V> value : values) {

            map.put(rawKey(value.getValue()), value.getScore());
        }
        return map;
    }
}
